package com.qf.controller;

import com.qf.captcha.CaptchaCodeManager;
import com.qf.pojo.DtsAdmin;
import com.qf.service.DtsPermissionService;
import com.qf.service.DtsRoleService;
import com.qf.util.*;
import com.qf.util.Base64;
import com.qf.util.UUID;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import lombok.extern.log4j.Log4j;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

import static com.qf.util.AdminResponseCode.AUTH_CAPTCHA_EXPIRED;

/**
 * @author Zwnan
 */
@RestController
@RequestMapping("/admin/auth")
@CrossOrigin("*")
@Log4j
public class AdminAuthController {
    /**
     * http://localhost:8083/admin/auth/captchaImage
     *
     * 下行数据：
     * {
     *     "errno":0,
     *  	"data":	{
     *         "img":"/9j/4AAQSkZJRlZ/2Q==",
     *         "uuid":"b5ca22d8b9e14a88b2851da906d19e4f"
     *     },
     *     "errmsg":"成功"
     * }
     */
    @RequestMapping("/captchaImage")
    public Object getCode() throws Exception{
        String code = VerifyCodeUtils.generateVerifyCode(4);
        String uuid = UUID.randomUUID().toString(true);
        boolean isSuccess = CaptchaCodeManager.addToCache(uuid, code, 5);
        if(!isSuccess){
            log.error("【登录错误】验证码获取失败");
            return ResponseUtil.fail();
        }

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(116, 35, os, code);
        String codeImg = Base64.encode(os.toByteArray());

        //返回值
        Map data = new HashMap<>();
        data.put("img",codeImg );
        data.put("uuid", uuid);
        return ResponseUtil.ok(data);
    }

    @PostMapping("/login")
    public Object login(@RequestBody String body) throws Exception{
        String username = JacksonUtil.parseString(body, "username");
        String password = JacksonUtil.parseString(body, "password");
        String code = JacksonUtil.parseString(body, "code");
        String uuid = JacksonUtil.parseString(body, "uuid");

        if (StringUtils.isEmpty(username)){
            return ResponseUtil.fail(805,"用户名不能为空");
        }
        if (StringUtils.isEmpty(password)){
            return ResponseUtil.fail(806,"密码不能为空");
        }
        if (StringUtils.isEmpty(code)){
            return ResponseUtil.fail(805,"验证码不能为空");
        }
        if (StringUtils.isEmpty(uuid)){
            return ResponseUtil.fail(805,"uuid不能为空");
        }

        //验证码校验
        String cachedCaptcha = CaptchaCodeManager.getCachedCaptcha(uuid);
//        if (!code.equalsIgnoreCase(cachedCaptcha)){
//            return AdminResponseUtil.fail(AUTH_CAPTCHA_EXPIRED);
//        }

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,password);
        try{
            //底层 realm 连接Mysql数据库 校验用户名及密码
            subject.login(usernamePasswordToken);
        }catch (UnknownAccountException e){

            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_INVALID_ACCOUNT_ERR);
        }catch (IncorrectCredentialsException e){

            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_INVALID_PASSWORD_ERR);
        }catch (LockedAccountException e){

            return AdminResponseUtil.fail(AdminResponseCode.ADMIN_LOCK_ACCOUNT);
        }
        return ResponseUtil.ok(subject.getSession().getId());
    }

    /**
     *
     * {
     *     "errno":0,
     *     "data":{
     *         "roles":["超级管理员"],
     *         "name":"qianfeng",
     *         "perms":["*"],
     *         "avatar":"https://dss1.bdstatic.com/6OF1,499686101&fm=85&app=79&f=JPEG?w=121&h=75&s=81B24C32D40"
     *     },
     *     "errmsg":"成功"
     * }
     * @return
     */
    @Autowired
    private DtsRoleService dtsRoleService;

    @Autowired
    private DtsPermissionService dtsPermissionService;
    @Autowired
    private ApplicationContext applicationContext;
    @GetMapping("/info")
    public Object info(){
        Map map = new HashMap();
        Subject subject = SecurityUtils.getSubject();
        DtsAdmin  dtsAdmin  = (DtsAdmin) subject.getPrincipal();
        map.put("name",dtsAdmin.getUsername() );
        map.put("avatar", dtsAdmin.getAvatar());
        Integer[] roleIds = dtsAdmin.getRoleIds();
        Set<String> roles = dtsRoleService.findByIds(roleIds);
        System.out.println(roles);
        map.put("roles", roles);
        String basicPackage = "com.qf.controller";
        Set<String> perms = dtsPermissionService.findpermissionByRoleIds(roleIds);
        Collection<String> permApi = toApi(perms);

        map.put("perms",permApi);

        return ResponseUtil.ok(map);
    }

    private Collection<String> toApi(Set<String> perms) {

        if (perms.contains("*")){
            return Arrays.asList("*");
        }
            String basicPackage = "com.qf.controller";
            List<Permission> permissions = PermissionUtil.listPermission(applicationContext, basicPackage);
            return permissions.stream().filter(permission ->{
                if (perms.contains(permission.getRequiresPermissions().value()[0])){
                    return true;
                }else {
                    return false;
                }
            }).map(Permission::getApi).collect(Collectors.toSet());
    }

    @PostMapping("/logout")
    public Object logout(){

        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return ResponseUtil.ok();
    }
}
